﻿using MaterialDesignThemes.Wpf;
using Prism.Commands;
using StarryEdge.Core;
using StarryEdge.Core.Device;
using StarryEdge.Core.Enums;
using StarryEdge.Core.Manager;
using StarryEdge.Core.Models;
using StarryEdge.Core.Parameter;
using StarryEdge.Menu.Device.ViewModels.Dialog;
using StarryEdge.Menu.Device.Views;
using StarryEdge.Menu.Device.Views.Dialog;
using StarryEdge.Parameter;
using StarryEdge.WPF.Lang;
using StarryEdge.WPF.Tool;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace StarryEdge.Menu.Device.ViewModels
{
    public class DeviceConfigViewModel : StarryEdge.Core.IViewModelLife
    {
        #region 双向绑定属性
        public ObservableCollection<string> ServiceNameList { get; set; }

        public IEnumerable<string> TaskTypeList
        {
            get
            {
                return _objectManager.GetTaskNames();
            }
        }

        public IEnumerable<DeviceTypes> Foods
        {
            get
            {
                foreach (DeviceTypes c in (DeviceTypes[])Enum.GetValues(typeof(DeviceTypes)))
                {
                    yield return c;
                }
            }
        }
        /// <summary>
        /// 是否是多设备
        /// </summary> 
        public bool IsDevices { get; set; }
        public bool IsNet { get; set; } = true;
        public bool IsUDP { get; set; }
        public DeviceTypes Types { get; set; }

        public string StartAddress { get; set; }
        public int StartProt { get; set; }
        public string EndAddress { get; set; }
        public int EndPort { get; set; }
        public string ServiceName { get; set; }
        public string TaskName { get; set; }
        #endregion
        public DeviceInfoManage DeviceInfo { get; set; }
        public TemporaryParameter Temporary{ get; set; }
        private IObjectManager _objectManager;
        private IDialogHost _dialogHost;
        private SystemConfigParameter _systemConfig;
        public DeviceConfigViewModel(IDeviceInfoManage deviceInfo, ITemporaryParameter temporary, ISystemConfigParameter systemConfig, IObjectManager objectManager, IDialogHost dialogHost)
        {
            _systemConfig = (SystemConfigParameter)systemConfig;
            DeviceInfo = (DeviceInfoManage)deviceInfo;
            Temporary = (TemporaryParameter)temporary;
            _dialogHost = dialogHost;
            _objectManager = objectManager;
            ServiceNameList = new ObservableCollection<string>();
        }

        public DelegateCommand AfterWeighingServer => new DelegateCommand(() =>
        {
            if (Temporary.Status_Software)
            {
                _dialogHost.DialogShow(LangManager.Instance.ToolTip["DeviceRunNoEdit"], LogLevel.Warning, isOperation: true, PopUpTypes.Global);
                return;
            }
            if (DeviceInfo.DeviceInfos.Any(x => x.ServiceName == ServiceName && x.TaskName == "扫描信号") && TaskName == "扫描信号")
            {
                _dialogHost.DialogShow("相同服务名只能存在一个[扫描信号]任务", LogLevel.Warning, isOperation: true, PopUpTypes.Global);
                return;
            }
            if (IsDevices)
            {
                DeviceInfo.AddDevices(StartAddress, StartProt.ToString(), EndAddress, EndPort.ToString(), IsNet, IsUDP, Types, TaskName, ServiceName);
            }
            else
            {
                DeviceInfo.Add(StartAddress, StartProt, StartProt, IsNet, IsUDP, Types, TaskName, ServiceName);
            }
            ObservableCollection<DeviceInfoModel> deviceClientModels = new ObservableCollection<DeviceInfoModel>();
            foreach (var task in _objectManager.GetTaskNames())
            {
                foreach (var item in Enum.GetValues<DeviceTypes>())
                {
                    foreach (var name in ServiceNameList)
                    {
                        var list = DeviceInfo.DeviceInfos.Where(x => x.DeviceType == item && x.ServiceName == name && x.TaskName == task).ToArray();
                        if (list == null) { continue; }
                        for (int i = 0; i < list.Count(); i++)
                        {
                            deviceClientModels.Add(list[i]);
                        }
                    }
                }
            }
            DeviceInfo.DeviceInfos.Clear();
            foreach (var item in deviceClientModels)
            {
                DeviceInfo.DeviceInfos.Add(item);
            }
            DeviceInfo.Save();
        });

        public DelegateCommand<ListView> SelectDisable => new DelegateCommand<ListView>(sender =>
        {
            if (Temporary.Status_Software)
            {
                _dialogHost.DialogShow(LangManager.Instance.ToolTip["DeviceRunNoEdit"], LogLevel.Warning, true, PopUpTypes.Global);
                return;
            }
            foreach (var item in sender.SelectedItems)
            {
                (item as DeviceInfoModel).Index = 999;
            }
            DeviceInfo.Save();
        });

        public DelegateCommand<DeviceInfoModel> DeviceConfigMouseDoubleClick => new DelegateCommand<DeviceInfoModel>(sender =>
        {
            if (sender == null) { return; }
            if (Temporary.Status_Software)
            {
                _dialogHost.DialogShow(LangManager.Instance.ToolTip["DeviceRunNoEdit"], LogLevel.Warning, true, PopUpTypes.Global);
                return;
            }
            //if (ViewContent.DataContext is DeviceConfig.IDeviceViewModel sendeModel)
            //{
            //    sendeModel.SendModel(sender);
            //    return;
            //}
            if (_systemConfig.StringSignalList.Any(x => x.Name == sender.ServiceName))
            {
                _ = DialogHost.Show(new DeviceModify() { DataContext = new DeviceModifyPopupDialog<string>(sender, _systemConfig.AddressSignalList, _systemConfig.StringSignalList, _objectManager, DeviceInfo) }, PopUpTypes.Global.ToString());
            }
            else
            {
                _ = DialogHost.Show(new DeviceModify() { DataContext = new DeviceModifyPopupDialog<int>(sender, _systemConfig.AddressSignalList, _systemConfig.StringSignalList, 
                    _objectManager, DeviceInfo) }, PopUpTypes.Global.ToString());
            }
        });

        private Action<DeviceInfoModel, DeviceInfoModel> _copy;

        public DelegateCommand<ListView> SelectDelete => new DelegateCommand<ListView>(sender =>
        {
            if (_copy == null)
            {
                _copy = ConversionHelper.CopyClass<DeviceInfoModel, DeviceInfoModel>();
            }
            if (Temporary.Status_Software)
            {
                _dialogHost.DialogShow(LangManager.Instance.ToolTip["DeviceRunNoEdit"], LogLevel.Warning, true, PopUpTypes.Global);
                return;
            }
            List<DeviceInfoModel> models = new List<DeviceInfoModel>();
            foreach (var item in sender.SelectedItems)
            {
                DeviceInfoModel model = new DeviceInfoModel();
                _copy.Invoke(item as DeviceInfoModel, model);
                models.Add(model);
            }
            foreach (var item in models)
            {
                var model = DeviceInfo.DeviceInfos.FirstOrDefault(x => x.IsSocket == item.IsSocket 
                && x.TaskName == item.TaskName
                    && x.ServiceName == item.ServiceName
                    && x.Index == item.Index
                    && x.DeviceType == item.DeviceType
                    && x.Port == item.Port
                    && x.IPCOM == item.IPCOM);
                if (model != null)
                {
                    DeviceInfo.DeleteDevice(model);
                }
            }
            DeviceInfo.Save();
        });

        public void Enter()
        {
            foreach (var item in _systemConfig.StringSignalList)
            {
                ServiceNameList.Add(item.Name);
            }
            foreach (var item in _systemConfig.AddressSignalList)
            {
                ServiceNameList.Add(item.Name);
            }
        }

        public void Exit()
        {

        }
    }
}
